package com.cxl.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cxl.config.AjaxResult;
import com.cxl.entity.*;
import com.cxl.service.*;
import com.cxl.springboot.starter.fileupload.FileResult;
import com.cxl.springboot.starter.fileupload.FileUpLoadService;
import com.cxl.utils.WebUtils;
import com.cxl.utils.pdf.FileUtils;
import com.cxl.utils.pdf.PDFUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 酒店表 前端控制器
 * </p>
 *
 * @author cuixuelei
 * @since 2022-02-17
 */
@RestController
@RequestMapping("/hotel")
public class HotelController {


    @Autowired
    private IUserService userService;

    @Autowired
    private IHotelService hotelService;

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * @description: 登陆
     * @date 2022/2/17
     **/
    @PostMapping(value = "login")
    public AjaxResult login(@RequestBody User user) {
        //redis防重复提交
        if (!redisTemplate.opsForValue().setIfAbsent(JSON.toJSONString(user), null, 10, TimeUnit.SECONDS)) {
            return AjaxResult.err(500, "不可重复提交");
        }
        //判断用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", user.getUsername());
        queryWrapper.eq("pwd", user.getPwd());
        User userone = userService.getOne(queryWrapper);
        if (userone != null) {
            //存在
            String token = UUID.randomUUID().toString();
            userone.setToken(token);
            userone.setPwd(null);  //密码不传前端,保障用户信息
            redisTemplate.opsForValue().set(token, userone);   //信息存入redis,后期判断角色
            return AjaxResult.ok(userone);
        }
        return AjaxResult.err(500, "用户信息错误,请重新输入");
    }


    /**
     * @description: 列表
     * @date 2022/2/17
     **/
    @GetMapping(value = "list")
//    @Cacheable(cacheNames = "list", key = "#pageNum")
//    @CacheEvict(cacheNames = "list",allEntries = true)
    public AjaxResult list(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "3") Integer pageSize) {
        redis();
        PageHelper.startPage(pageNum, pageSize);
        List<Hotel> list = redislist(pageNum, pageSize);
        PageInfo<Hotel> pg = new PageInfo<>(list);
        pg.setPageNum(pageNum);
        pg.setPageSize(pageSize);
        return AjaxResult.ok(pg);
    }


    /**
     * @description: 列表数据源于redis
     * @date 2022/2/17
     **/
    public List<Hotel> redislist(Integer pageNum, Integer pageSize) {
        List<Hotel> list = null;
        if (redisTemplate.hasKey("list")) {
            list = redisTemplate.opsForList().range("list", (pageNum * pageSize) - 1, (pageNum * pageSize) + pageSize - 1);
        } else {
            list = hotelService.list();
            //维度拼接
            for (Hotel hotel : list) {
                hotel.setVdo(hotelService.findByVdo(hotel));
            }
            redisTemplate.opsForList().rightPushAll("list", list);
        }
        return list;
    }


    /**
     * @description: PDF导出
     * @date 2022/2/17
     **/
    @GetMapping(value = "topdf1")
    public void topdf(HttpServletResponse response) throws Exception {
        List<Hotel> list = hotelService.list();
        //维度拼接
        for (Hotel hotel : list) {
            hotel.setVdo(hotelService.findByVdo(hotel));
        }
        Document document = new Document();
        PdfWriter pdfWriter = PDFUtils.createDoc(document, PDFUtils.getFilePath() + "hotel.pdf");
        PDFUtils.addTable(pdfWriter,
                new String[]{"序号", "酒店名称", "酒店星级", "酒店品牌", "最低价格", "最高价格", "经纬度", "大床房数", "中床房数", "小床房数"},
                new String[]{"id", "name", "level", "brand", "minprice", "maxprice", "vdo", "dbed", "zbed", "xbed"},
                list, 30, 800);
        document.close();
        pdfWriter.close();

        //电子签章
        PDFUtils.markImage(PDFUtils.getPicPath() + "1.jpg",
                new FileInputStream(PDFUtils.getFilePath() + "hotel.pdf"),
                new FileOutputStream(PDFUtils.getFilePath() + "hotelimg.pdf"),
                "电子签章"
        );

        FileUtils.download(response, PDFUtils.getFilePath() + "hotelimg.pdf", "dow.pdf", 0);
    }


    /**
     * @description: PDF导出 预览
     * @date 2022/2/17
     **/
    @GetMapping(value = "topdf2")
    public void topdf2(HttpServletResponse response) throws Exception {
        List<Hotel> list = hotelService.list();
        //维度拼接
        for (Hotel hotel : list) {
            hotel.setVdo(hotelService.findByVdo(hotel));
        }
        Document document = new Document();
        PdfWriter pdfWriter = PDFUtils.createDoc(document, PDFUtils.getFilePath() + "hotel.pdf");
        PDFUtils.addTable(pdfWriter,
                new String[]{"ID", "酒店名称", "酒店星级", "酒店品牌", "最低价格", "最高价格", "经纬度", "大床房数", "中床房数", "小床房数"},
                new String[]{"id", "name", "level", "brand", "minprice", "maxprice", "vdo", "dbed", "zbed", "xbed"},
                list, 30, 800);
        document.close();
        pdfWriter.close();

        //电子签章
        PDFUtils.markImage(PDFUtils.getPicPath() + "1.jpg",
                new FileInputStream(PDFUtils.getFilePath() + "hotel.pdf"),
                new FileOutputStream(PDFUtils.getFilePath() + "hotelimg.pdf"),
                "电子签章"
        );

        FileUtils.download(response, PDFUtils.getFilePath() + "hotelimg.pdf", "dow.pdf", 1);
    }


    public void redis() {
        redisTemplate.delete("list");
    }


    @Autowired
    private FileUpLoadService fileUpLoadService;


    /**
     * @description: 上传
     * @date 2022/2/17
     **/
    @PostMapping(value = "tofile")
    public FileResult tofile(@RequestParam(value = "file") MultipartFile file) throws IOException {
        return fileUpLoadService.upload(file);
    }


    /**
     * @description: 发布酒店
     * @date 2022/2/17
     *
     * (3)校验经纬度是否合法，经度,整数部分为0-180,小数部分为0到6位，纬度,整数部分为0-90,小数部分为0到6位（3分）
     **/
    @PostMapping(value = "add")
    @CacheEvict(cacheNames = "list",allEntries = true)  //清理缓存
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody Hotel hotel) {
        //用户权限
        String token = WebUtils.getRequest().getHeader("token");
        User user = (User) redisTemplate.opsForValue().get(token);
        if (user.getRole().equals("0")) {
            String[] split = (hotel.getInvdo() + "").split("\\.");
            int length = split[1].length();
            String[] split2 = (hotel.getOutvdo() + "").split("\\.");
            int length2 = split[1].length();
            if (Integer.valueOf(split[0]) >= 0 && Integer.valueOf(split[0]) <= 180 && length <= 6 && length >= 0) {
                if (Integer.valueOf(split2[0]) >= 0 && Integer.valueOf(split2[0]) <= 90 && length2 <= 6 && length2 >= 0) {
                    if (redisTemplate.opsForValue().setIfAbsent(token + JSON.toJSONString(hotel), null, 10, TimeUnit.SECONDS)) {
                        //(6)列表数据来源于Redis，添加酒店时保证Mysql和Redis数据一致性(2分)
                        hotelService.save(hotel);
                        redisTemplate.delete("list");
                        List<Hotel> list = hotelService.list();
                        redisTemplate.opsForList().rightPushAll("list", list);
                        return AjaxResult.ok();
                    }
                    return AjaxResult.err(500, "不可重复提交");
                }
                return AjaxResult.err(500, "纬度,整数部分为0-90,小数部分为0到6位");
            }
            return AjaxResult.err(500, "经度,整数部分为0-180,小数部分为0到6位");
        } else {
            return AjaxResult.err(500, "普通用户无法发布信息");
        }
    }


    /**
     * @description: 酒店下拉框
     * @date 2022/2/17
     **/
    @GetMapping(value = "gethotel")
    public List<Hotel> gethotel() {
        return hotelService.list();
    }


    /**
     * @description: 客房下拉框
     * @date 2022/2/17
     **/
    @GetMapping(value = "gettenants")
    public List<Tenant> gettenants() {
        return tenantService.list();


    }
    @GetMapping(value = "gettenants2")
    public Tenant gettenants2(Integer tid) {
        return tenantService.getByTenant(tid);
    }

    @Autowired
    private IVipService vipService;


    @GetMapping(value = "getvips")
    public List<Vip> getvips() {
        return vipService.list();
    }

    @Autowired
    private ITenantService tenantService;
    
    /**
     * @description:    添加房客
     * @date 2022/2/17
     **/
    @PostMapping(value = "addtenant")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addtenant(@RequestBody Tenant tenant) {
        String token = WebUtils.getRequest().getHeader("token");
        if (!redisTemplate.opsForValue().setIfAbsent(token + JSON.toJSONString(tenant), null, 10, TimeUnit.SECONDS)) {
            return AjaxResult.err(500, "不可重复提交");
        }
        //添加房客信息
        tenantService.save(tenant);
//        int i = 1/0;
        //增加酒店房间数量
        //房间信息按床型分列进行显示，显示各自的房间数量
        if (tenant.getBed().equals("0")) {
            Hotel byId = hotelService.getById(tenant.getHid());
            byId.setDbed(byId.getDbed()+1);
            hotelService.updateById(byId);
        }
        if (tenant.getBed().equals("1")) {
            Hotel byId = hotelService.getById(tenant.getHid());
            byId.setZbed(byId.getZbed()+1);
            hotelService.updateById(byId);
        }
        if (tenant.getBed().equals("3")) {
            Hotel byId = hotelService.getById(tenant.getHid());
            byId.setXbed(byId.getXbed()+1);
            hotelService.updateById(byId);
        }
        return AjaxResult.ok();
    }



    @Autowired
    private IYuyueService yuyueService;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    /**
     * @description:    预约
     * @date 2022/2/17
     **/
    @PostMapping(value = "addyuyue")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addyuyue(@RequestBody Yuyue yuyue) {
        String token = WebUtils.getRequest().getHeader("token");
        if (!redisTemplate.opsForValue().setIfAbsent(token + JSON.toJSONString(yuyue), null, 10, TimeUnit.SECONDS)) {
            return AjaxResult.err(500, "不可重复提交");
        }
        //添加预约信息
        yuyueService.save(yuyue);
        //预约信息保存成功后，使用kafka异步向预约用户的手机发送短信
        redisTemplate.opsForValue().set(JSON.toJSONString(yuyue),yuyue);
        kafkaTemplate.send("test","yuyue",JSON.toJSONString(yuyue));
        return AjaxResult.ok();
    }
}
